package com.example.mq.mqserver.dataCenter;

import com.example.mq.common.MqException;
import com.example.mq.mqserver.core.Binding;
import com.example.mq.mqserver.core.Exchange;
import com.example.mq.mqserver.core.MSGQueue;
import com.example.mq.mqserver.core.Message;

import java.io.IOException;
import java.util.LinkedList;
import java.util.List;

/**
 * 硬盘数据管理
 * 对外提供统一的管理接口 管理以下:
 * 1.数据库: 交换机、队列、两者的绑定关系
 * 2.数据文件: 消息
 * 上层代码并不关心数据的存储位置 所以用同一的接口更方便管理
 */
public class DiskDataCenter {
    private DataBaseManager dataBaseManager = new DataBaseManager();
    private MessageFileManager messageFileManager = new MessageFileManager();

    //进行 数据库 以及 数据文件的初始化
    public void init(){
        dataBaseManager.init();
        messageFileManager.init();
    }

    //创建交换机
    public void insertExchange(Exchange exchange){
        dataBaseManager.insertExchange(exchange);
    }

    //查找所有交换机
    public List<Exchange> selectAllExchanges(){
        return dataBaseManager.selectAllExchanges();
    }

    //删除交换机
    public void deleteExchange(String exchangeName){
        dataBaseManager.deleteExchange(exchangeName);
    }

    // 封装队列操作
    public void insertQueue(MSGQueue queue) throws IOException {
        dataBaseManager.insertQueue(queue);
        // 创建队列的同时, 不仅仅是把队列对象写到数据库中, 还需要创建出对应的目录和文件
        messageFileManager.createQueueFiles(queue.getName());
    }

    public List<MSGQueue> selectAllQueues() {
        return dataBaseManager.selectAllMSGQueues();
    }

    public void deleteQueue(String queueName) throws IOException {
        dataBaseManager.deleteQueue(queueName);
        // 删除队列的同时, 不仅仅是把队列从数据库中删除, 还需要删除对应的目录和文件
        messageFileManager.destroyQueueFiles(queueName);
    }


    // 封装绑定操作
    public void insertBinding(Binding binding) {
        dataBaseManager.insertBinding(binding);
    }

    public List<Binding> selectAllBindings() {
        return dataBaseManager.selectAllBindings();
    }

    public void deleteBinding(Binding binding) {
        dataBaseManager.deleteBinding(binding);
    }


    // 封装消息操作
    public void sendMessage(MSGQueue queue, Message message) throws IOException, MqException {
        messageFileManager.sendMessage(queue, message);
    }

    public void deleteMessage(MSGQueue queue, Message message) throws IOException, ClassNotFoundException, MqException {
        messageFileManager.deleteMessage(queue, message);
        //每删除一条消息 就要判断是否需要进行GC操作,避免无效消息过多形成冗余
        if (messageFileManager.checkIsGC(queue.getName())) {
            messageFileManager.gc(queue);
        }
    }

    public LinkedList<Message> loadAllMessageFromQueue(String queueName) throws IOException, MqException, ClassNotFoundException {
        return messageFileManager.loadAllMessageFromQueue(queueName);
    }
}
